home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #2
/
Monster Media No. 2 (Monster Media)(1994).ISO
/
prog_gen
/
gcoope10.zip
/
LOWSTRM.C
< prev
next >
Wrap
Text File
|
1994-07-21
|
4KB
|
176 lines
/*
LowStream class definition for GCOOPE 1.0
Compatible with experimental strong typing option.
Designed 7/21/94 by Brian L. Price
Released as Public Domain July, 1994.
This is NOT a standalone class, it must be inherited by a
class that also inherits the Dynmem class.
NOTE: This class definition is an extension class, while it
provides no functionality on its own, it extends the capabilities
of another class.
The purpose of this class is to provide low level stream i/o
compatibility to any inheritor of the Dynmem class. In other
words, this class can be used to allow arrays and strings to be
targets of a stream i/o operation.
The technique illustrated here is roughly analogous to a C++
friend concept but does its job with complete instance and class
encapsulation. The only presumption made by this class is that
an inheritor also inherits the Dynmem class. (Or has inherited
a class which has inherited Dynmem.)
Another feature shown here is the local storage of the
instance handle adjusted for a call to Dynmem, thus avoiding a
lengthy recursive call to steer with a fake instance every time a
call to a Dynmem method is made. This technique could be made even
faster by storing the method function addresses thus avoiding the
dispatcher overhead. (At the cost of storing two method function
pointers (8 bytes).)
*/
#define CLASS LowStream
#include "gcoope10.h"
#include <stdio.h>
object CLASS;
extern object Dynmem;
typedef struct {
object dynhandle;
word strmPos;
stat strmErr;
} instVars;
USEGEN(addressOf);
USEGEN(sizeOf);
USEGEN(getPos);
USEGEN(setPos);
USEGEN(putByte);
USEGEN(getByte);
USEGEN(strmErr);
USEGEN(clrErr);
cmethod object m4New(object instance)
{
instVars * ivptr;
object fake=0;
if(NULL==(ivptr=makeInst(&instance))) return 0;
ivptr->strmPos=0;
ivptr->strmErr=FUNCOKAY;
(tag) fake = (tag) instance;
ivptr->dynhandle=steer(Dynmem, fake);
return instance;
}
imethod long m4getPos(object instance)
{
return ((instVars *) getIVptr(instance))->strmPos;
}
imethod object m4strmErr(object instance)
{
return ((instVars *) getIVptr(instance))->strmErr;
}
imethod object m4setPos(object instance, long offset, int start)
{
instVars * ivptr;
word size;
if(NULL==(ivptr=getIVptr(instance))) goto err;
size=((WRDRV)g)(GEN(sizeOf))(ivptr->dynhandle);
size--;
switch (start) {
case SEEK_SET : ivptr->strmPos = 0;
case SEEK_CUR : break;
case SEEK_END : ivptr->strmPos= size; break;
default : goto err; }
offset+=ivptr->strmPos;
if(offset >= 0 && offset <= size)
{
ivptr->strmPos=(word) offset;
if(offset==0) ivptr->strmErr=FUNCOKAY;
return FUNCOKAY;
}
err:
return FUNCFAIL;
}
imethod object m4putByte(object instance, byte newData)
{
instVars * ivptr;
byte * bptr;
if(NULL==(ivptr=getIVptr(instance)) || ivptr->strmErr) goto err;
bptr=((byte *)((VDPTRRV) g)(GEN(addressOf))(ivptr->dynhandle))
+ ivptr->strmPos++;
*bptr=newData;
if(ivptr->strmPos >= ((WRDRV) g)(GEN(sizeOf))(ivptr->dynhandle))
ivptr->strmErr=FUNCFAIL;
return FUNCOKAY;
err:
return FUNCFAIL;
}
imethod int m4getByte(object instance)
{
instVars * ivptr;
byte * bptr;
if(NULL==(ivptr=getIVptr(instance)) || ivptr->strmErr) goto err;
bptr=((byte *)((VDPTRRV) g)(GEN(addressOf))(ivptr->dynhandle))
+ ivptr->strmPos++;
if(ivptr->strmPos >= ((WRDRV) g)(GEN(sizeOf))(ivptr->dynhandle))
ivptr->strmErr=FUNCFAIL;
return *bptr;
err:
return -1;
}
imethod object m4clrErr(object instance)
{
instVars * ivptr;
if(NULL==(ivptr=getIVptr(instance))) return FUNCFAIL;
else
{
ivptr->strmErr=FUNCOKAY;
return FUNCOKAY;
}
}
CLASS_INSTALL
{
if(END==(CLASS=g(New)(Class, 0, sizeof(instVars), END))
|| addGMthd(CLASS,New,(method) m4New) || ADDGM(getPos)
|| ADDGM(strmErr) || ADDGM(setPos) || ADDGM(putByte)
|| ADDGM(getByte) || ADDGM(clrErr)) return FUNCFAIL;
else return FUNCOKAY;
}